﻿using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;
using Sprout.Schedule.Web.Utils;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace Sprout.Schedule.Web.Attributes
{
    /// <summary>
    /// 请求操作验证
    /// </summary>
    public class ValidationAttribute : ActionFilterAttribute
    {
        /// <summary>
        /// 在动作执行异步
        /// </summary>
        /// <param name="context"></param>
        /// <param name="next"></param>
        /// <returns></returns>
        public override async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next)
        {
            var validate = await ValidateActionAsync(context);
            if (validate)
            {
                var modelState = context.ModelState;
                if (!modelState.IsValid)
                {
                    context.Result = new ObjectResult(ModelStateHelper.GetModelStateResult(modelState));
                }
                else
                {
                    await next();
                }
            }
        }

        /// <summary>
        /// 验证功能
        /// </summary>
        /// <returns></returns>
        private async Task<bool> ValidateActionAsync(ActionExecutingContext context)
        {
            var descriptor = context.ActionDescriptor as Microsoft.AspNetCore.Mvc.Controllers.ControllerActionDescriptor;
            //获取controller上的特性
            var actionAttributes = descriptor.ControllerTypeInfo.GetCustomAttributes(true);
            //判断特性
            var isAllowAnonymous = actionAttributes.Any(n => n is AllowAnonymousAttribute);
            if (isAllowAnonymous == true)
            {
                return true;
            }
            //获取方法上的特性
            actionAttributes = descriptor.MethodInfo.GetCustomAttributes(true);
            //判断特性
            isAllowAnonymous = actionAttributes.Any(n => n is AllowAnonymousAttribute);
            //获取特性
            //var allowAnonymousAttribute = actionAttributes.FirstOrDefault(n => n.GetType() == typeof(AllowAnonymousAttribute));

            if (isAllowAnonymous == true)
            {
                return true;
            }

            var user = LoginHelper.GetLoginUser(context.HttpContext);

            if (user == null)
            {
                context.Result = new RedirectResult("~/Login/Login");
                return false;
            }
            return true;
        }
    }
}
